package com.learn.security.theory.message_digest;

import com.learn.security.utils.message_digest.SHAUtil;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.digests.SHA224Digest;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.security.MessageDigest;
import java.security.Security;

/**
 * SHA算法
 * <p>
 * 特点：固定长度摘要信息
 * <p>
 * 类别：                      摘要长度       实现方法（jdk基本实现，bc补充，cc简化）
 * SHA-1:                  160             jdk
 * SHA-2:
 * SHH-224         224             bc
 * SHH-256         224             jdk
 * SHH-384         384             jdk
 * SHH-512         512             jdk
 */
public class SHATest {

    private static final String encodeStr = "SHA test";

    public static void main(String[] args) {
        SHAUtil();
        jdkSHA1();
        bcSHA1();
        bcSHA224();
        bcSHA224b();
        ccSHA1();

    }

    // 用SHAUtil实现:SHA1
    private static void SHAUtil() {
        byte[] sha1Bytes = SHAUtil.encryptSHA(encodeStr.getBytes());
        System.out.println("SHAUtil sha-1:" + Hex.encodeHexString(sha1Bytes));
    }

    // 用jdk实现:SHA1
    private static void jdkSHA1() {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA");
            md.update(encodeStr.getBytes());
            System.out.println("jdk sha-1:" + Hex.encodeHexString(md.digest()));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 用bouncy castle实现:SHA1
    private static void bcSHA1() {
        Digest digest = new SHA1Digest();
        digest.update(encodeStr.getBytes(), 0, encodeStr.getBytes().length);
        byte[] sha1Bytes = new byte[digest.getDigestSize()];
        digest.doFinal(sha1Bytes, 0);
        System.out.println("bc sha-1:" + org.bouncycastle.util.encoders.Hex.toHexString(sha1Bytes));
    }


    // 用bouncy castle实现:SHA224
    private static void bcSHA224() {
        Digest digest = new SHA224Digest();
        digest.update(encodeStr.getBytes(), 0, encodeStr.getBytes().length);
        byte[] sha224Bytes = new byte[digest.getDigestSize()];
        digest.doFinal(sha224Bytes, 0);
        System.out.println("bc sha-224:" + org.bouncycastle.util.encoders.Hex.toHexString(sha224Bytes));
    }

    // 用bouncy castle与jdk结合实现:SHA224
    private static void bcSHA224b() {
        try {
            Security.addProvider(new BouncyCastleProvider());
            MessageDigest md = MessageDigest.getInstance("SHA224");
            md.update(encodeStr.getBytes());
            System.out.println("bc and JDK sha-224:" + Hex.encodeHexString(md.digest()));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 用common codes实现实现:SHA1
    private static void ccSHA1() {
        System.out.println("common codes SHA1 - 1 :" + DigestUtils.sha1Hex(encodeStr.getBytes()));
        System.out.println("common codes SHA1 - 2 :" + DigestUtils.sha1Hex(encodeStr));
    }
}
